home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / dir / VisualShell117.lha / src / history.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-29  |  10.3 KB  |  352 lines

  1.         /*********************************
  2.          *                               *
  3.          *   Visual Shell v1.17  10/92   *
  4.          *                               *
  5.          *     by Torsten Jürgeleit      *
  6.          *                               *
  7.          *         history part          *
  8.          *                               *
  9.          *********************************/
  10.  
  11.     /* Includes */
  12.  
  13. #include "includes.h"
  14. #include "imports.h"
  15. #include "protos.h"
  16.  
  17.     /* View ConMan command line history */
  18.  
  19.    VOID
  20. action_history(VOID)
  21. {
  22.    struct FileRequest     *freq = &file_req[active_freq];
  23.    struct HistoryRequest  *hreq = &history_req;
  24.    BYTE  *force_line = NULL;
  25.    SHORT error = VSH_STATUS_NORMAL;
  26.  
  27.    print_status(VSH_STATUS_HISTORY);
  28.    hcomp_freq_cursor(freq);
  29.    print_info_line(INFO_LINE_MODE_EMPTY);
  30.    print_fkey_text(FKEY_MODE_NONE);
  31.    if ((error = read_history(hreq)) == VSH_STATUS_NORMAL) {
  32.       print_history_page(hreq);
  33.       do {
  34.      ULONG signals = Wait(SIGF_INTUITION | SIGF_ACTION);
  35.  
  36.      if (signals & SIGF_INTUITION) {   /* timing events from Intuition */
  37.         struct IntuiMessage  *msg;
  38.  
  39.         if (msg = (struct IntuiMessage *)GetMsg(con_window->UserPort)) {
  40.            ULONG class = msg->Class;
  41.  
  42.            ReplyMsg((struct Message *)msg);
  43.            switch (class) {
  44.           case REFRESHWINDOW :
  45.              print_history_page(hreq);
  46.              break;
  47.           case INTUITICKS :
  48.              if (status != VSH_STATUS_HISTORY) {
  49.             if (error_delay-- < 0) {   /* remove error msg in status line */
  50.                print_status(VSH_STATUS_HISTORY);
  51.             }
  52.              }
  53.              if (auto_repeat) {
  54.             scroll_history_req();
  55.              }
  56.              break;
  57.            }
  58.         }
  59.      }
  60.      if (signals & SIGF_ACTION) {
  61.         switch (action) {
  62.            case VSH_ACTION_F1 :   /* jump to line */
  63.           jump_to_history_line(hreq);
  64.           break;
  65.            case VSH_ACTION_F2 :   /* start searching */
  66.           search_history_line(hreq, HISTORY_SEARCH_MODE_FIRST);
  67.           break;
  68.            case VSH_ACTION_F3 :   /* continue searching */
  69.           search_history_line(hreq, HISTORY_SEARCH_MODE_NEXT);
  70.           break;
  71.            case VSH_ACTION_F4 :   /* print current page */
  72.           print_history_text(hreq, PRINT_MODE_PAGE);
  73.           break;
  74.            case VSH_ACTION_F5 :   /* print whole text */
  75.           print_history_text(hreq, PRINT_MODE_ALL);
  76.           break;
  77.            case VSH_ACTION_NUM_ENTER :   /* force into command line */
  78.           force_line = get_history_line(hreq);
  79.           break;
  80.            case VSH_ACTION_SCROLL_UP :
  81.            case VSH_ACTION_SCROLL_DOWN :
  82.            case VSH_ACTION_SCROLL_PAGE_UP :
  83.            case VSH_ACTION_SCROLL_PAGE_DOWN :
  84.            case VSH_ACTION_SCROLL_TOP :
  85.            case VSH_ACTION_SCROLL_BOTTOM :
  86.           scroll_history_req();
  87.           break;
  88.         }
  89.      }
  90.       } while (action != VSH_ACTION_QUIT && action != VSH_ACTION_ESC &&
  91.                             force_line == NULL);
  92.       print_status(VSH_STATUS_FREE_LINE_LIST);
  93.       free_list(hreq->hr_Display.d_List, (LONG)sizeof(struct LineNode));
  94.       DosFreeMem(hreq->hr_Buffer);
  95.       if (!force_line) {
  96.      status = error;
  97.      draw_requesters(DRAW_MODE_CLEAR);
  98.       } else {
  99.      print_status(VSH_STATUS_EXECUTE_HISTORY_LINE);   /* execute selected history line */
  100.      action_display_mode();
  101.      print_fkey_text(FKEY_MODE_NONE);
  102.      error = force_string(force_line, (USHORT)strlen(force_line),
  103.                            FORCE_MODE_NEWLINE_COPY);
  104.       }
  105.    } else {
  106.       hcomp_freq_cursor(freq);
  107.       print_info_line(INFO_LINE_MODE_NORMAL);
  108.    }
  109.    change_fkey_text();
  110.    print_status(error);
  111. }
  112.     /* Print history page */
  113.  
  114.    VOID
  115. print_history_page(struct HistoryRequest  *hreq)
  116. {
  117.    print_status(VSH_STATUS_HISTORY);
  118.    SetAPen(con_rport, (LONG)COLOR0);
  119.    RectFill(con_rport, (LONG)(BORDER_LEFT - 2), (LONG)(BORDER_TOP_HIDDEN
  120.       - 1), (LONG)(vsh_width - BORDER_RIGHT    + 1), (LONG)(cli_vpos - 3));
  121.    draw_line(COLOR1, (USHORT)2, (USHORT)(BORDER_TOP_HIDDEN - 2), (USHORT)
  122.               (vsh_width - 3), (USHORT)(BORDER_TOP_HIDDEN - 2));
  123.    print_hreq_lines(hreq,
  124.              (struct LineNode *)hreq->hr_Display.d_FirstVisibleNode,
  125.                 (USHORT)0, hreq->hr_Display.d_VisibleLines);
  126.    hcomp_hreq_cursor(hreq);
  127.    print_fkey_text(FKEY_MODE_HISTORY);
  128. }
  129.     /* Read command line history into buffer and build line list */
  130.  
  131.    SHORT
  132. read_history(struct HistoryRequest  *hreq)
  133. {
  134.    LONG  len;
  135.    BYTE  *buffer;
  136.    SHORT error;
  137.  
  138.    if ((struct CommandLineInterface *)BTOC(_parent_proc->pr_CLI) ==
  139.                                  save_cli) {   /* no EndCLI ? */
  140.       if ((len = dos_packet(con_input_fhandle->fh_Type,
  141.           CONMAN_ACTION_READ_HISTORY, con_input_fhandle, (LONG)NULL,
  142.                              0L)) == DOSFALSE) {
  143.      error = VSH_ERROR_WRONG_CONMAN_VERSION;
  144.       } else {
  145.      if (!(buffer = DosAllocMem(len))) {
  146.         error = VSH_ERROR_OUT_OF_MEM;
  147.      } else {
  148.         hreq->hr_Buffer = buffer;
  149.         if (dos_packet(con_input_fhandle->fh_Type,
  150.               CONMAN_ACTION_READ_HISTORY, con_input_fhandle, buffer,
  151.                              len) == DOSFALSE) {
  152.            error = VSH_ERROR_WRONG_CONMAN_VERSION;
  153.         } else {
  154.            print_status(VSH_STATUS_BUILD_LINE_LIST);
  155.                if (build_history_line_list(hreq) == FALSE) {
  156.           error = VSH_ERROR_OUT_OF_MEM;
  157.            } else {
  158.           hreq->hr_Display.d_FirstVisibleNode = hreq->hr_Display.d_List->mlh_Head;
  159.           return(VSH_STATUS_NORMAL);
  160.            }
  161.            print_status(VSH_STATUS_FREE_LINE_LIST);
  162.            free_list(hreq->hr_Display.d_List, (LONG)
  163.                            sizeof(struct LineNode));
  164.         }
  165.         DosFreeMem(buffer);
  166.      }
  167.       }
  168.    }
  169.    return(error);
  170. }
  171.     /* Jump to an history line */
  172.  
  173.    VOID
  174. jump_to_history_line(struct HistoryRequest  *hreq)
  175. {
  176.    ULONG  line, num_entries = hreq->hr_Display.d_NumEntries;
  177.    USHORT vlines = hreq->hr_Display.d_VisibleLines;
  178.    SHORT  error = VSH_STATUS_HISTORY;
  179.  
  180.    if (get_input(INPUT_MODE_HISTORY_LINE, NULL)) {
  181.       line = gadget_info.LongInt;
  182.       if (! line || line > num_entries) {
  183.      error = VSH_ERROR_INVALID_LINE_NUM;
  184.       } else {
  185.      move_hreq_cursor(hreq, (struct LineNode *)
  186.                       get_list_node(hreq->hr_Display.d_List,
  187.                       hreq->hr_Display.d_NumEntries, line));
  188.       }
  189.    }
  190.    print_fkey_text(FKEY_MODE_HISTORY);
  191.    print_status(error);
  192. }
  193.     /* Search line with specified text in history */
  194.  
  195.    VOID
  196. search_history_line(struct HistoryRequest  *hreq, USHORT mode)
  197. {
  198.    struct LineNode  *lnode = get_history_node_under_cursor(hreq);
  199.    BYTE   *search_text, *default_input = &hreq->hr_LastSearchString[0];
  200.    ULONG  num_entries = hreq->hr_Display.d_NumEntries;
  201.    USHORT len, vlines = hreq->hr_Display.d_VisibleLines;
  202.    SHORT  error = VSH_STATUS_HISTORY;
  203.  
  204.    if (mode == HISTORY_SEARCH_MODE_FIRST) {
  205.       if (!(search_text = get_input(INPUT_MODE_HISTORY_SEARCH,
  206.                               default_input))) {
  207.      len = 0;
  208.       } else {
  209.      if (len = strlen(search_text)) {
  210.  
  211.         /* Save new search text */
  212.         strcpy(default_input, search_text);
  213.      }
  214.       }
  215.    } else {
  216.       print_fkey_text(FKEY_MODE_NONE);
  217.       if (! lnode) {
  218.      len = 0;
  219.       } else {
  220.      lnode       = (struct LineNode *)lnode->ln_Node.mln_Succ;
  221.      search_text = default_input;
  222.      len         = strlen(search_text);
  223.       }
  224.    }
  225.    if (error == VSH_STATUS_HISTORY && len) {
  226.       if (!(lnode = search_line_node(lnode, search_text, len))) {
  227.      error = VSH_ERROR_SEARCH_FAILED;
  228.       } else {
  229.      move_hreq_cursor(hreq, lnode);
  230.       }
  231.    }
  232.    print_fkey_text(FKEY_MODE_HISTORY);
  233.    print_status(error);
  234. }
  235.     /* Print history text */
  236.  
  237.    VOID
  238. print_history_text(struct HistoryRequest  *hreq, USHORT mode)
  239. {
  240.    struct LineNode  *lnode;
  241.    ULONG i, end;
  242.    BPTR  fh;
  243.    SHORT error = VSH_STATUS_HISTORY;
  244.  
  245.    print_status(VSH_STATUS_PRINT_TEXT);
  246.    print_fkey_text(FKEY_MODE_NONE);
  247.    if (mode == PRINT_MODE_PAGE) {
  248.       lnode = (struct LineNode *)history_req.hr_Display.d_FirstVisibleNode;
  249.       end   = history_req.hr_Display.d_VisibleLines;
  250.    } else {
  251.       lnode = (struct LineNode *)history_req.hr_Display.d_List->mlh_Head;
  252.       end   = history_req.hr_Display.d_NumEntries;
  253.    }
  254.    if (!(fh = (BPTR)Open("PRT:", (LONG)MODE_NEWFILE))) {
  255.       error = VSH_ERROR_NO_PRINTER;
  256.    } else {
  257.       enable_abort = 1;
  258.       for (i = 0; i < end && error == VSH_STATUS_HISTORY; i++) {
  259.      if (CheckAbort(NULL)) {
  260.         error = VSH_ERROR_ABORTED;
  261.      } else {
  262.         if (FPrintf(fh, "%s\n", build_hreq_line(hreq, lnode,
  263.                           LINE_MODE_NO_FILL)) < 0) {
  264.            error = VSH_ERROR_PRINTING_FAILED;
  265.         } else {
  266.            lnode = (struct LineNode *)lnode->ln_Node.mln_Succ;
  267.         }
  268.      }
  269.       }
  270.       enable_abort = 0;
  271.       Close(fh);
  272.    }
  273.    print_fkey_text(FKEY_MODE_HISTORY);
  274.    print_status(error);
  275. }
  276.     /* Get history line under cursor */
  277.  
  278.    BYTE *
  279. get_history_line(struct HistoryRequest  *hreq)
  280. {
  281.    struct LineNode  *lnode = get_history_node_under_cursor(hreq);
  282.    BYTE   *buffer = &path1_buffer[0];
  283.    USHORT len;
  284.  
  285.    if (!lnode) {
  286.       buffer = NULL;
  287.    } else {
  288.       len = *(lnode->ln_Line - 1);
  289.       strncpy(buffer, lnode->ln_Line, (size_t)len);
  290.       *(buffer + len++) = '\n';   /* append new line char */
  291.       *(buffer + len)   = '\0';
  292.    }
  293.    return(buffer);
  294. }
  295.     /* Get history node under cursor of specified history requester */
  296.  
  297.    struct LineNode *
  298. get_history_node_under_cursor(struct HistoryRequest  *hreq)
  299. {
  300.    struct LineNode  *lnode = NULL;
  301.    SHORT i, cursor_line = hreq->hr_CursorLine;
  302.  
  303.    if (cursor_line != -1) {
  304.       lnode = (struct LineNode *)hreq->hr_Display.d_FirstVisibleNode;
  305.       for (i = cursor_line; i; i--) {
  306.      lnode = (struct LineNode *)lnode->ln_Node.mln_Succ;
  307.       }
  308.    }
  309.    return(lnode);
  310. }
  311.     /* Move cursor to specified entry in history requester */
  312.  
  313.    VOID
  314. move_hreq_cursor(struct HistoryRequest  *hreq, struct LineNode  *lnode)
  315. {
  316.    ULONG  num_entries = hreq->hr_Display.d_NumEntries, cursor_line;
  317.    USHORT i, vlines = hreq->hr_Display.d_VisibleLines;
  318.  
  319.    if (lnode) {
  320.       hcomp_hreq_cursor(hreq);
  321.       cursor_line = lnode->ln_Pos - 1;
  322.       if (num_entries > vlines) {
  323.      if (cursor_line < (vlines / 2)) {
  324.         lnode = (struct LineNode *)hreq->hr_Display.d_List->mlh_Head;
  325.      } else {
  326.         if (cursor_line > (num_entries - vlines / 2)) {
  327.            lnode = (struct LineNode *)
  328.                       hreq->hr_Display.d_List->mlh_TailPred;
  329.            i = vlines - 1;
  330.         } else {
  331.            i = vlines / 2;
  332.         }
  333.         for ( ; i; i--) {
  334.            lnode = (struct LineNode *)lnode->ln_Node.mln_Pred;
  335.         }
  336.         cursor_line -= lnode->ln_Pos - 1;
  337.      }
  338.       } else {
  339.      lnode = (struct LineNode *)hreq->hr_Display.d_List->mlh_Head;
  340.       }
  341.       if (lnode != (struct LineNode *)hreq->hr_Display.d_FirstVisibleNode) {
  342.      hreq->hr_Display.d_FirstVisibleNode = (struct MinNode *)lnode;
  343.      print_hreq_lines(hreq, lnode, (USHORT)0, vlines);
  344.       } else {
  345.      print_hreq_lines(hreq, (struct LineNode *)
  346.             hreq->hr_Display.d_FirstVisibleNode, (USHORT)0, vlines);
  347.       }
  348.       hreq->hr_CursorLine = cursor_line;
  349.       hcomp_hreq_cursor(hreq);
  350.    }
  351. }
  352.